package game;

import java.awt.Rectangle;
import java.awt.image.*;
import javax.imageio.*;
import javax.swing.ImageIcon;

import java.io.*;

public class Mario extends Sprite {
	public static final long serialVersionUID = 1L;
	protected int jumpHeight;
	protected boolean canJump;
	protected boolean jumping;
	
	public Mario(Level g, int x, int y){
		try{
			level = g;
			this.x = x;
			this.y = y;
			frames = new ImageIcon[8];
			BufferedImage sheet = ImageIO.read(new File("images/spritesheet.gif"));
			frames[0] = new ImageIcon(sheet.getSubimage(15, 89, 16, 28));
			frames[1] = new ImageIcon(sheet.getSubimage(33, 89, 16, 28));
			frames[2] = new ImageIcon(sheet.getSubimage(52, 89, 16, 28));
			frames[3] = new ImageIcon(sheet.getSubimage(70, 89, 16, 28));
			frames[4] = new ImageIcon(sheet.getSubimage(111, 89, 16, 28));
			frames[5] = new ImageIcon(sheet.getSubimage(129, 89, 16, 28));
			frames[6] = new ImageIcon(sheet.getSubimage(148, 89, 16, 28));
			frames[7] = new ImageIcon(sheet.getSubimage(166, 89, 16, 28));
			animations = new int[6][];
			animations[0] = new int[1];
			animations[1] = new int[1];
			animations[2] = new int[4];
			animations[3] = new int[4];
			animations[4] = new int[1];
			animations[5] = new int[1];
			animations[0][0] = 0;
			animations[1][0] = 7;
			for(int i = 0; i<3; i++){
				animations[2][i] = i+1;
			}
			animations[2][3] = 2;
			for(int i = 0; i<3; i++){
				animations[3][i] = i+4;
			}
			animations[3][3] = 5;
			animations[4][0] = 3;
			animations[5][0] = 4;
			currentAnim = 4;
			currentFrame = 0;
			slowDown = 3;
			x = 50;
			y = 100;
			prevX = x;
			prevY = y;
			downMotion = 0;
			moveBounds = new Rectangle();
			scale = 2;
			speed = 6;
			jumpHeight = 35;
			canJump = false;
			jumping = false;
			xMotion = 0;
			fxSpeed = speed;
			width = frames[0].getIconWidth();
			height = frames[0].getIconHeight();
			fxJumpHeight = jumpHeight;
			fxGravity = level.canvas.gravity;
			fxFriction = level.canvas.friction;
			curWidth = (int)(width*scale);
			curHeight = (int)(height*scale);
		}catch (IOException e){}
	}
	
	@Override
	public void update(){
		super.update();
		animationCalculations();
		jump();
		calculateYPosition();
		createMovebounds();
	}
	
	public void resetEffects(){
		fxSpeed = speed;
		fxJumpHeight = jumpHeight;
		fxGravity = level.canvas.gravity;
		fxFriction = level.canvas.friction;
	}
	
	public void death(){
		if(!level.canvas.muted)
			level.canvas.addMusic(new ClipPlayer("images/sfx.wav", level.canvas.settings.soundVolume));
	    new GameoverMenu(level.canvas);
	}
	
	//does horizontal movement calculations based on animation
		protected void animationCalculations(){
			nextFrame();
			if(getAnim() == 1){
				if(looped){
					setAnim(2);
				}
			}else if(getAnim() == 0){
				if(looped){
					setAnim(3);
					speedIndex = 0;
				}
			}
			//calculate direction && movement based on animation
			if(getAnim() == 2){ //moving left
				if(xMotion > -(scale*fxSpeed)){
					xMotion -= fxFriction;
					if(xMotion < -(scale*fxSpeed)){
						xMotion = -(scale*fxSpeed);
					}
				}
				if(xMotion < -(scale*fxSpeed)){
					xMotion += fxFriction;
				}
			}else if(getAnim() == 3){ //moving right
				if(xMotion < scale*fxSpeed){
					xMotion += fxFriction;
					if(xMotion > scale*fxSpeed){
						xMotion = scale*fxSpeed;
					}
				}
				if(xMotion > scale*fxSpeed){
					xMotion -= fxFriction;
				}
			}else{
				//slow down sprite until 0
				if(xMotion < 0){
					xMotion += fxFriction;
					if(xMotion > 0){
						xMotion = 0;
					}
				}else if(xMotion > 0){
					xMotion -= fxFriction;
					if(xMotion < 0){
						xMotion = 0;
					}
				}
			}
			x += (int)xMotion; //calculate new x
			//prevent from going over bounds of the frame
			if(x < 0){ 
				x = 0;
				xMotion = 0;
			}else if(x > level.canvas.maxWidth-curWidth){
				x = level.canvas.maxWidth-curWidth;
				xMotion = 0;
			}
		}
		
		//calculates jumping
		protected void jump(){
			if(jumping && canJump){
				downMotion -= fxJumpHeight;
				jumping = false;
				if(!level.canvas.muted)
					level.canvas.addMusic(new ClipPlayer("images/jump.wav", level.canvas.settings.soundVolume));
			}
			canJump = false;
		}
		
		//calculate the new yPosition
		protected void calculateYPosition(){
			downMotion += fxGravity;
			y += downMotion;
			//so that mario doesn't go offscreen
			if(y < -level.canvas.maxHeight+level.canvas.height){
				y = -level.canvas.maxHeight+level.canvas.height;
				downMotion = 0;
			}else if(y > level.canvas.height-curHeight){
				y = level.canvas.height-curHeight;
				downMotion = 0;
				canJump = true;
			}
			if(downMotion > 100){
				downMotion = 100;
			}else if(downMotion < -100){
				downMotion = -100;
			}
		}
		
		//creates movebounds for the sprite
		protected void createMovebounds(){
			if(prevX < x){//moved right
				if(prevY < y){ // if moved down
					moveBounds.setBounds(prevX, prevY, x-prevX+curWidth, y-prevY+curHeight);
				}else{
					moveBounds.setBounds(prevX, y, x-prevX+curWidth, prevY-y+curHeight);
				}
			}else{
				if(prevY < y){
					moveBounds.setBounds(x, prevY, prevX-x+curWidth, y-prevY+curHeight);
				}else{
					moveBounds.setBounds(x, y, prevX-x+curWidth, prevY-y+curHeight);
				}
			}
		}
	
	@Override
	public void calculateIntersectEffects(GameRectangle rect){}
	
	public void bottomHit(GameRectangle g){
		super.bottomHit(g);
		canJump = true;
	}
}
